import pandas as pd
import _params
from os import path
import datetime

'''
 参数设置
'''
# 行情数据最少所需天数
HQ_DAYS = 100
# 统计的行情类型
HQ_TYPE = '1W'
# 周期内涨跌幅正常幅度
HQ_SPREAD = 0.6
# 所需要的数据字段
HQ_FIELDS = ['secID', 'ticker', 'tradeDate', 'marketValue', 'PB', 'preClosePrice', 'closePrice', 'isOpen',
             'highestPrice', 'lowestPrice']
# 每个周期取前多少只股票
HQ_NUM = 3
# 读取股票列表数据
stock_list = pd.read_excel(_params.__STOCK_LIST_FULL_FILE_PATH, converters={'ticker':str})

stock_hq_all = pd.DataFrame()
# 根据股票日线数据，获取周线数据
N = 0
for ticker in stock_list['ticker']:
    print("开始处理日线数据：code:" + ticker)
    # 判断是否存在数据文件
    if not path.exists(_params.__STOCK_HQ_FILE_PATH + ticker + ".xlsx"):
        print("数据文件不存在，code:" + ticker)
        continue

    # 读取股票日线数据
    stock_hq = pd.read_excel(_params.__STOCK_HQ_FILE_PATH + ticker + ".xlsx", converters={'ticker':str}, parse_dates=['tradeDate'])
    # 如果数据过少，直接过滤
    if len(stock_hq) < HQ_DAYS:
        print("日线行情数据太少，code:" + ticker + ";length:" + str(len(stock_hq)))
        continue
    # 将日线数据转成所需的类型
    stock_hq = stock_hq[HQ_FIELDS]
    #stock_hq['tradeDate'] = stock_hq['tradeDate'].apply(lambda x : datetime.datetime.strptime(str(x), '%Y%m%d'))
    stock_hq.set_index('tradeDate', inplace=True)
    # 将日线数据转成所需的周期，比如周线
    # 去除非交易日数据
    stock_hq = stock_hq[stock_hq['isOpen'] == 1]
    # 删除一字板
    stock_hq = stock_hq[stock_hq['highestPrice'] != stock_hq['lowestPrice']]
    # 删除新股影响，将第一个交易日数据除去，相当于等新股较稳定后才纳入股票池
    stock_hq = stock_hq[stock_hq['closePrice']/stock_hq['preClosePrice'] < 1.1]
    stock_hq_period = stock_hq.resample(HQ_TYPE,how='last')
    stock_hq_period['preClosePrice'] = stock_hq['preClosePrice'].resample(HQ_TYPE,how='first')
    stock_hq_period = stock_hq_period[stock_hq_period['ticker'].notnull()]
    stock_hq_period = stock_hq_period[stock_hq_period['PB'] > 0]
    # 计算周期涨跌幅
    stock_hq_period['profit'] = stock_hq_period['closePrice'] / stock_hq_period['preClosePrice'] - 1
    stock_hq_period['nextProfit'] = stock_hq_period['profit'].shift(-1)
    # 考虑到停牌以及拆股等因素，将周期内增长或下跌过多的数据去除
    stock_hq_period = stock_hq_period[-HQ_SPREAD < stock_hq_period['nextProfit']]
    stock_hq_period = stock_hq_period[stock_hq_period['nextProfit'] < HQ_SPREAD]
    stock_hq_all = pd.concat([stock_hq_all, stock_hq_period])
    print("--处理日线数据结束：code:" + ticker)

#stock_hq_all.to_excel("fama.xlsx")

stock_hq_all['tradeDate'] = stock_hq_all.index
# 根据日期进行分组，并取出每个周期的前N小值数据（市值*PB）
stock_hq_all['fama'] = stock_hq_all['marketValue'] * stock_hq_all['PB']
# 按照日期和fama值排序（递增）
stock_hq_all = stock_hq_all.sort_values(by=['tradeDate', 'fama'])
# 按日期分组，取前HQ_NUM数据
stock_bs = stock_hq_all.groupby(by='tradeDate').head(HQ_NUM)
stock_bs.to_excel("fama_result.xlsx")
# 统计盈亏情况（假设买入的股票等分所有资金）
stock_bs = stock_bs.groupby('tradeDate').sum() / HQ_NUM
# 累计盈亏
stock_bs['profitSum'] = (stock_bs['nextProfit'] + 1).cumprod() * 100
stock_bs.to_excel("fama_profit.xlsx")